
#include "Emitter.h"
#include "Particle.h"
#include "..\\..\\SGD Wrappers\SGD_GraphicsManager.h"


Emitter::Emitter()
{
	bPlay = false;
}


Emitter::Emitter(const Emitter& that)
{
	sFileName = that.sFileName;
	sEmitterName = that.sEmitterName;
	bPlay = that.bPlay;
	bRepeat = that.bRepeat;
	fSpawnRate = that.fSpawnRate;
	fSpawnTime = that.fSpawnTime;
	iMaxParticles = that.iMaxParticles;
	flyweight = that.flyweight;

	position = that.position;
	normal = that.normal;
}

Emitter::~Emitter()
{
	Unload();
}

// Accessors
const char* Emitter::GetEmitterName()
{
	return sEmitterName.c_str();
}

const char* Emitter::GetFileName()
{
	return sFileName.c_str();
}

int Emitter::GetMaxParticles()
{
	return iMaxParticles;
}

float Emitter::GetSpawnRate()
{
	return fSpawnRate;
}

float Emitter::GetSpawnTime()
{
	return fSpawnTime;
}

bool Emitter::GetRepeat()
{
	return bRepeat;
}

bool Emitter::GetPlay()
{
	return bPlay;
}

SGD::Point Emitter::GetPosition()
{
	return position;
}

SGD::Vector Emitter::GetNormal()
{
	return normal;
}

Flyweight& Emitter::GetFlyweight()
{
	return flyweight;
}

// Mutators
void Emitter::SetEmitterName(const char* name)
{
	sEmitterName = name;
}

void Emitter::SetFileName(const char* name)
{
	sFileName = name;
}

void Emitter::SetMaxParticles(int num)
{
	iMaxParticles = num;
}

void Emitter::SetSpawnRate(float time)
{
	fSpawnRate = time;
}

void Emitter::SetSpawnTime(float time)
{
	fSpawnTime = time;
}

void Emitter::SetRepeat(bool repeat)
{
	bRepeat = repeat;
}

void Emitter::SetPlay(bool play)
{
	if (play)
		Load();
	bPlay = play;
}

void Emitter::SetPosition(SGD::Point p)
{
	position = p;
	GetFlyweight().SetPosition(p);
}

void Emitter::SetNormal(SGD::Vector n)
{
	normal = n;
}

void Emitter::Load()
{
	int parts = GetMaxParticles() - deadList.size();
	for (int i = 0; i < parts; ++i)
	{
		deadList.push_back(new Particle());
	}
	flyweight.SetPosition(SGD::Point(250.0f, 400.0f));
}

void Emitter::Unload()
{
	Particle* temp;
	while (liveList.begin() != liveList.end())
	{
		temp = liveList.front();
		liveList.pop_front();

		if (temp != nullptr)
		{
			delete temp;
		}
	}

	while (deadList.begin() != deadList.end())
	{
		temp = deadList.front();
		deadList.pop_front();
		if (temp != nullptr)
		{
			delete temp;
		}
	}
}

void Emitter::Update(float dt)
{
	Particle* p;
	if (0.0f >= (GetSpawnTime() - dt) && GetPlay())
	{
		if (0 < deadList.size())
		{
			p = deadList.front();
			deadList.pop_front();
			p->Reset(flyweight);
			liveList.push_back(p);
		}
		SetSpawnTime(GetSpawnRate());
	}
	else
	{
		SetSpawnTime(GetSpawnTime() - dt);
	}

	for (std::list<Particle*>::iterator iter = liveList.begin(); iter != liveList.end();)
	{
		p = (*iter);
		++iter;
		if (false == p->Update(flyweight, dt))
		{
			liveList.remove(p);
			if (GetRepeat())
				deadList.push_back(p);
			else
				delete p;
		}
	}

	if (liveList.size() + deadList.size() == 0 && !GetRepeat())
		SetPlay(false);
}

void Emitter::Render()
{
	for (std::list<Particle*>::iterator iter = liveList.begin(); iter != liveList.end(); ++iter)
	{
		(*iter)->Render(flyweight);
	}
}